Previous | Chapter contents | Next | Book PDF
AppleScript has always aimed at scripting the model layer of an application. This is a good thing. Much of the time, the most efficient way for a script to do something is not the best way for a user to do the same thing. If scripting were concerned solely with providing access to the user interface of an application, it would just be glorified journaling. Sometimes, however, you do want to affect certain aspects of the user interface while scripting, usually in scripts that are more like macros.
Scripts that work with model objects are like batch processing. They go in and do their thing and do not need or want the user's involvement. A scripting system that extracts data from a database, processes it through other applications and then sends it all to a page-layout program to generate the classified ads page for a newspaper is an example of such batch processing. The whole idea in these batch-processing cases is not to involve the user. In these cases, you want to go directly to the application's model objects and just get the work done.
Scripts that work with view objects are like macros. They do a very specific manipulation of an application, usually a relatively small and self-contained one, and their purpose is to automate a small repetitive task for the user. For instance, a script that gets the selected graphic in a page-layout program, adds a caption beneath it, and sets up blue-line guides along the outer edges of the resulting group to aid with alignment would be a script of this type. The macro characteristic of these types of scripts is that the user does a little preparation (like selecting the graphic), invokes the script, then continues on when it is done. For this type of script, your application should expose some of its user-interface structure to scripts. You should make things such as windows and selections scriptable to enable this type of scripting. However, the exposure of these user-interface structures should be an addition to the support provided for directly scripting the model objects of your application.
The scriptability support in the Yellow Box frameworks is geared towards making it easy for an application to expose its model objects to scripters. Scriptability is the easiest to implement when the actual model objects of your application are the objects it wants to support for scripting. Keep this fact in mind when you design your application's model layer.
There are certain programming practices to avoid when you design your application's model layer for scripting. Many simple applications keep state in their view layer (that is, in a user-interface object). For instance, a Preferences panel controller might be implemented so that the state of a Boolean attribute is "stored" in a checkbox in the Preferences panel and is retrieved and set with the state and setState: methods. First, keeping state in a view object is generally not a good strategy for data that is part of a document's model because it is antithetical to the MVC pattern. If a script needs to be able to access and modify state, the state value should be separated from the view layer and stored in a model object or, if it doesn't belong in the model layer, in a controller object. Often this separation is necessary or desirable even without scripting as a consideration. For example, if a Preferences-panel controller stores current preference settings only in the controls of the panel, it cannot answer any questions about the current settings without loading the panel. If other parts of the application need to find out about preferences even if the user has not brought up the Preferences panel (a likely situation), then it would be much better if the preferences controller itself stored the settings. This would allow it to avoid having to load a nib file (a somewhat expensive activity) until it is actually needed.
The same argument holds for primitive behaviors as well. For instance, if you have a Find panel, instead of implementing the logic to actually perform the find in the action method invoked by the Find Next button, you should probably define some API on your document class or on your model objects that is capable of performing the find. The Find Next button's action method would then invoke this API. The advantage of this scheme is that when you want scripts to be able to search documents, you can let the script go through the document or model API instead of having to hack up scripted access to the Find panel itself, which is less desirable.
Previous | Chapter contents | Next | Book PDF